//
//  EZSocket.swift
//
//  Created by ellzu gu on 2021/5/27.
//

import Foundation
import CFNetwork

/// Socke 实现了 TCP UDP ICMP
/// ITSocket采用非阻塞式
/// ITSocket默认 接口/变量 非线程安全，调用者需要确保在同一线程调用
/// 在ITSocket+Async扩展提供线程安全调用方法
open class EZSocket {
    /// socket的运行线程 --
    public private(set) var socketQueue: DispatchQueue
    /// 接收缓冲区
    private var buffer: UnsafeMutableRawBufferPointer
    /// 回调线程
    public var delegateQueue: DispatchQueue = DispatchQueue.main;
    /// 发送中的包
    var sendingPackets: Array<Packet> = Array<Packet>.init();
    //IP协议
    public private(set) var saFamily: Int32 = 0
    //本地网络名字
    public private(set) var ifaName: String? = nil
    /// 本地地址
    public  private(set) var localAddress: sockaddr_storage? = nil
    /// 服务器地址
//    var serverAddress : sockaddr? = nil;
    public private(set) var serverAddress: sockaddr_storage? = nil
    /// BSD SockeID
    private(set) var socketID: Int32 = 0;
    /// 连接中
    private(set) var connecting: Bool = false;
    /// 已经连接
    private(set) var connected: Bool = false;
    /// 接收源事件监听器
    private var receiveSource: DispatchSourceRead? = nil
    private var receiveSourceResume: Bool = false
    /// 发送源事件监听器
    private var sendSource: DispatchSourceWrite? = nil;
    private var sendSourceResume: Bool = false;
    /// socket类型
    private(set) var socketType: Int32 = 0;//SOCK_DGRAM or SOCK_STREAM or SOCK_RAW;
    /// socket协议类型
    public var protol: Int32 = 0;// IPPROTO_UDP IPPROTO_TCP IPPROTO_ICMP/IPPROTO_ICMPV6
    
    /// 链接完毕后回调代码块
    private var connectedCompletion : ((EZError?)->Void)? = nil;
    
    /// 接收超时计时器
    private var receiveTimerSource: DispatchSourceTimer? = nil;
    /// 开始接收时间标记
    private var receiveBeginTimestamp: TimeInterval = 0;
    /// 接收超时设置 0 循环接收 -1 接收单次 无超时设置。大于0 表示单次接收 数值是超时时间
    private var receiveTimeoutInterval: TimeInterval = 0;
    /// 接收后回调代码块
    private var receiveCompletion: ((_ data: Data?,_ fromAddress: sockaddr_storage?, _ error: EZError?)->Void)? = nil;
    private var acceptHandler:((_ nSocket: EZSocket)->Void)? = nil
    
    public var sendableHandler: (()->Void)? = nil
    public var receiveableHandler: (()->Void)? = nil
    
    /// 初始化
    /// - Parameters:
    ///   - socketType: socket类型
    ///   - protol: socket协议类型
    ///
    public init(socketType : Int32, protol : Int32, socketQueue: DispatchQueue = EZSocket.sharedSocketQueue) {
        self.socketType = socketType;
        self.protol = protol;
        self.socketQueue = socketQueue
        self.buffer = Self.sharedBuffer(socketQueue)
    }
    
    deinit {
        assert(self.socketID == 0)
    }
    
    public var socketLocalAddress: sockaddr_storage? {
        guard self.socketID > 0 else {
            return nil
        }
        var sockaddrStorage = sockaddr_storage()
        let code = withUnsafeMutableBytes(of: &sockaddrStorage) { (buffer: UnsafeMutableRawBufferPointer)-> Int32 in
            guard let addr = buffer.baseAddress?.assumingMemoryBound(to: sockaddr.self) else {
                return -1
            }
            var size: socklen_t = socklen_t(buffer.count)
            return getsockname(self.socketID, addr, &size)
        }
        if code != 0 {
            return nil
        }
        return sockaddrStorage
    }
}

//MARK: prepare
extension EZSocket {
    
    /// 准备socket
    /// - Parameters:
    ///   - host: 目标地址
    ///   - hostPort: 目标端口
    ///   - local: 本机地址 IP or ifaName
    ///   - localPort: 本机端口
    /// - Returns: 如果失败返回错误
    public func prepare(host : String? = nil, hostPort : UInt16 = 0, local : String? = nil, localPort: UInt16 = 0, family: Int32 = 0) -> EZError? {
        var error : EZError? = nil;
        repeat {
            
            if (self.socketID > 0) {
                error = self.error(code: .StatusError);
                break;
            }
            
            if let host: String = host {
                self.serverAddress = AddressUtils.addressWithHost(host: host, hostPort: hostPort, family: family)
                if (self.serverAddress == nil) {
                    error = self.error(code: .DNSError);
                    break;
                }
                
                self.saFamily = Int32(self.serverAddress!.ss_family)
            }
            
            if (self.serverAddress == nil || local != nil) {
                (self.localAddress, self.ifaName) = AddressUtils.localAddress(local: local, port: localPort, family: Int32(self.saFamily))
                if (self.localAddress == nil) {
                    error = self.error(code: .InterfaceError);
                    break;
                }
                self.saFamily = Int32(self.localAddress?.ss_family ?? 0)
            }
            
            self.repairParameter()
            
            //创建Socket
            self.socketID = socket(Int32(self.saFamily), self.socketType, self.protol);
            if (self.socketID <= 0) {
                error = self.error(code: .SystemError, sub: self.error(systemCode: errno));
                break;
            }
            
            if self.socketType == SOCK_DGRAM && self.protol == IPPROTO_UDP {
                var reuseaddr : Int32 = 0;//是否允许UDP复用端口
                setsockopt(self.socketID, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, socklen_t(MemoryLayout<Int32>.size));
            }
            
            var nosigpipe : Int32 = 1;
            if (setsockopt(self.socketID, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, socklen_t(MemoryLayout<Int32>.size)) != 0) {
                error = self.error(code: .SystemError, sub: self.error(systemCode: errno));
                break;
            }
            
            //设置最大接收缓冲区
            var maxSize : Int32 = 65535;
            if setsockopt(self.socketID, SOL_SOCKET, SO_RCVBUF, &maxSize, socklen_t(MemoryLayout<Int32>.size)) != 0 {
                error = self.error(code: .SystemError, sub: self.error(systemCode: errno));
                break;
            }
            //设置最大发送缓冲区
            if setsockopt(self.socketID, SOL_SOCKET, SO_SNDBUF, &maxSize, socklen_t(MemoryLayout<Int32>.size)) != 0 {
                error = self.error(code: .SystemError, sub: self.error(systemCode: errno));
                break;
            }
            //非阻塞式
            if fcntl(self.socketID, F_SETFL, O_NONBLOCK) != 0 {
                error = self.error(code: .SystemError, sub: self.error(systemCode: errno));
                break;
            }
            
            //绑定本地出口网卡
            if var localAddress: sockaddr_storage = self.localAddress {
                var bindCode = withUnsafeMutableBytes(of: &localAddress) { (buffer: UnsafeMutableRawBufferPointer) -> Int32 in
                    guard let localAddressPointer = buffer.baseAddress?.assumingMemoryBound(to: sockaddr.self) else {
                        return -1
                    }
                    return Darwin.bind(self.socketID, localAddressPointer, socklen_t(localAddressPointer.pointee.sa_len));
                }
                if let ifaName = self.ifaName {
                    var nameIndex : UInt32 = if_nametoindex(ifaName.cString(using: .utf8));
                    let optCode : Int32 = setsockopt(self.socketID, IPPROTO_IP, IP_BOUND_IF, &nameIndex, socklen_t(MemoryLayout<UInt32>.size));
                    if optCode != 0 {
                        bindCode = optCode
                    }
                }
                if (bindCode != 0 ) {
                    error = self.error(code: .SystemError, sub: self.error(systemCode: errno));
                    break;
                }
            }
            
            self.receiveSource = DispatchSource.makeReadSource(fileDescriptor: self.socketID, queue: self.socketQueue);
            self.receiveSource?.setEventHandler {
                self.receiveSourceEvent()
            };
            
            self.sendSource = DispatchSource.makeWriteSource(fileDescriptor: self.socketID, queue: self.socketQueue);
            self.sendSource?.setEventHandler {
                self.sendSourceEvent()
            }
            
        }while(false);
        
        if (error != nil) {
            self.clean();
        }
        
        return error;
    }
    
    private func repairParameter() {
        //纠正一些参数
        if self.protol == IPPROTO_ICMPV6 && self.saFamily == AF_INET {
            self.protol = IPPROTO_ICMP
        } else if self.protol == IPPROTO_ICMP && self.saFamily == AF_INET6 {
            self.protol = IPPROTO_ICMPV6
        }
        
    }
    
}

//MARK: bind
extension EZSocket {
    /// 绑定到指定地址
    /// - Parameters:
    ///   - local: 本地 IP or 网卡名字 默认 nil  地址为 0.0.0.0
    ///   - port: 绑定的端口，必须提供
    /// - Returns: 如果绑定失败返回对应错误
    public func bind(local: String? = nil, port: UInt16) -> EZError? {
        return self.prepare(host: nil, hostPort: 0, local: local, localPort: port)
    }
    
    public func listen(local: String? = nil, port: UInt16) -> EZError? {
        if let error = self.prepare(host: nil, hostPort: 0, local: local, localPort: port) {
            return error
        }
        let sysCode = Darwin.listen(self.socketID, 1024)
        if sysCode < 0 {
            return self.error(systemCode: errno)
        }
        return nil
    }
}

//MARK: connect
extension EZSocket {
    
    /// 链接服务器
    /// - Returns: 成功返回 0
    public func connect(completion: /*@escaping*/ ((EZError?)->Void)? = nil) -> Void {
        self.connecting = true
        self.connectedCompletion = completion
        repeat {
            guard self.socketID > 0,
                  var serverAddress: sockaddr_storage = self.serverAddress,
                  let serverAddressPointer: UnsafePointer<sockaddr> = withUnsafeBytes(of: &serverAddress, { $0.baseAddress })?.assumingMemoryBound(to: sockaddr.self) else {
                self.completionConnect(error: self.error(code: .StatusError));
                break
            }
            errno = 0
            let connectCode : Int32 = Darwin.connect(self.socketID, serverAddressPointer, socklen_t(serverAddressPointer.pointee.sa_len));
            if connectCode == 0 {
                //链接成功,UDP直接成功
                self.completionConnect(error: nil);
                break
            }
            if errno == EAGAIN {
                //ICMP非阻塞会返回EAGAIN, 但这不是一个错误
                self.completionConnect(error: nil);
                break;
            }
            
            if (errno == EINPROGRESS ) {
                //TCP 需要等待
                let ret = self.checkConnect()
                if ( ret != 0) {
                    //连接已经终止
                    self.completionConnect(error: self.error(code: .ConnectError, sub: self.error(systemCode: ret)))
                } else {
                    //连接中
                    self.resumeSendSource()
                }
                break;
            }
            
            print("TODO:... socket connect 需要更多识别");
            self.completionConnect(error: self.error(code:.SystemError, sub: self.error(systemCode: errno)));
        }while(false);
    }
    
    /// 等待链接状态
    /// - Returns: 检查连接是否进行中
    private func checkConnect() -> Int32 {
        var fd : pollfd = pollfd.init();
        fd.fd = self.socketID;
        fd.events = Int16(POLLOUT);
        errno = 0;
        while (poll(&fd, 1, -1) == -1) {
            if errno != EINTR {
                return -1;
            }
            errno = 0;
        }
        var ret : Int32 = 0;
        var len : socklen_t = socklen_t(MemoryLayout<Int32>.size);
        if getsockopt(self.socketID, SOL_SOCKET, SO_ERROR, &ret, &len) != 0 {
            return -1;
        }
        return ret
    }
    
    private func completionConnect(error: EZError?) ->Void {
        self.connecting = false;
        self.connected = error == nil ? true : false;
        if let completion = self.connectedCompletion {
            self.delegateQueue.async {
                completion(error);
            }
        }
        self.connectedCompletion = nil;
    }
    
}

//MARK: send
extension EZSocket {
    
    /// 异步发送时候的队列处理
    /// - Returns:Void
    func flushPacket() -> Void {
        
        if (self.sendingPackets.count == 0) {
            return;
        }
        var error : EZError? = nil;
        let curPacket : Packet = self.sendingPackets.first!;
        var sendLen : Int = 0;
        repeat {
            let curTimestamp : TimeInterval = Date.init().timeIntervalSince1970;
            if (curPacket.timeoutInterval > 0.001 && curTimestamp - curPacket.beginTime > curPacket.timeoutInterval) {
                error = self.error(code: .TimeoutError);
                break;
            }
            if (self.socketID <= 0) {
                error = self.error(code: .DisconnectError);
                break;
            }

            sendLen = self.send(data: curPacket.data, position: curPacket.position, targetAddress: curPacket.targetAddress);
            
            if (sendLen < 0) {
                error = self.error(code: .SystemError, sub: self.error(systemCode: errno));
                break;
            }
            
            curPacket.position += sendLen;
            
        }while(false);
        
        if (error != nil || curPacket.position == curPacket.data.count) {
            //错误了，或者发完了，都是要结束的
            self.delegateQueue.async {
                curPacket.completion(error);
            }
            self.sendingPackets.removeFirst();
            self.flushPacket();
        } else {
            if sendLen == 0 {
                self.resumeSendSource();
            } else {
                self.flushPacket();
            }
        }
    }
    
    /// 发送
    /// - Parameters:
    ///   - buffer: 发送的数据
    ///   - bufferLen: 发送最大长度
    /// - Returns: 实际发送了多少 0 不是错误，负数 错误了
    public func send(data: Data, position: Int, targetAddress: sockaddr_storage? = nil) -> Int {
        if self.socketID <= 0 {
            return -1;
        }
        
        if self.connecting {
            return 0;
        }
        
        var sendLen : Int = 0;
        errno = 0;
        if  var targetAddress: sockaddr_storage = targetAddress,
            let targetAddressPointer: UnsafePointer<sockaddr> = withUnsafeBytes(of: &targetAddress, { $0.baseAddress })?.assumingMemoryBound(to: sockaddr.self) {
            data.withUnsafeBytes { (buffer: UnsafeRawBufferPointer) -> Void in
                sendLen = Darwin.sendto(self.socketID, buffer.baseAddress! + position, data.count - position, 0, targetAddressPointer, socklen_t(targetAddressPointer.pointee.sa_len));
            };
            if (sendLen < 0 && (errno == ENOBUFS || errno == EAGAIN)) {
                //内存不够，下次再发，不是错误
                sendLen = 0;
            }
        } else if self.connected {
            data.withUnsafeBytes { (buffer: UnsafeRawBufferPointer) -> Void in
                sendLen = Darwin.send(self.socketID, buffer.baseAddress! + position, data.count - position, 0);
            };
            if (sendLen < 0 && (errno == ENOBUFS || errno == EAGAIN)) {
                //内存不够，下次再发，不是错误
                sendLen = 0;
            }
        } else if var serverAddress: sockaddr_storage = self.serverAddress,
            let targetAddressPointer: UnsafePointer<sockaddr> = withUnsafeBytes(of: &serverAddress, { $0.baseAddress })?.assumingMemoryBound(to: sockaddr.self) {
            data.withUnsafeBytes { (buffer: UnsafeRawBufferPointer) -> Void in
                sendLen = Darwin.sendto(self.socketID, buffer.baseAddress! + position, data.count - position, 0, targetAddressPointer, socklen_t(targetAddressPointer.pointee.sa_len));
            };
            if (sendLen < 0 && (errno == ENOBUFS || errno == EAGAIN)) {
                //内存不够，下次再发，不是错误
                sendLen = 0;
            }
        } else {
            sendLen = -1;
        }
        if sendLen < 0 {
            //TODO...
        }
        return sendLen;
    }
    
    func suspendSendSource() -> Void {
        if (self.sendSourceResume) {
            self.sendSource?.suspend();
            self.sendSourceResume = false;
        }
    }
    
    public func resumeSendSource() -> Void {
        if (self.sendSourceResume == false) {
            self.sendSource?.resume();
            self.sendSourceResume = true;
        }
    }
    
    private func sendSourceEvent() -> Void {
        guard self.sendSource?.data ?? 0 > 0 else {
            return
        }
        
        self.suspendSendSource()
        
        if (self.connecting) {
            self.completionConnect(error: nil)
        }
        if let sendableHandler = self.sendableHandler {
            self.delegateQueue.async {
                sendableHandler()
            }
        }
        self.flushPacket()
    }
    
}

extension EZSocket {
    public func accept() {
        guard self.socketID > 0 else {
            return
        }
        var addr: sockaddr_storage = sockaddr_storage()
        var addLen: socklen_t = socklen_t(MemoryLayout<sockaddr_storage>.size)
        let childSocketID = withUnsafeMutableBytes(of: &addr) { (addrBuffer: UnsafeMutableRawBufferPointer) -> Int32 in
            guard let addrPointer = addrBuffer.baseAddress?.assumingMemoryBound(to: sockaddr.self) else {
                addLen = 0
                return 0
            }
            return Darwin.accept(self.socketID, addrPointer, &addLen)
        }
        guard childSocketID > 0 else {
            return
        }
        let socket = EZSocket(socketType: self.socketType, protol: self.protol, socketQueue: self.socketQueue)
        socket.delegateQueue = self.delegateQueue
        socket.socketID = childSocketID
        socket.serverAddress = addr
        socket.connected = true
        socket.saFamily = Int32(addr.ss_family)
        
        //设置最大接收缓冲区
        var maxSize : Int32 = 65535;
        if setsockopt(socket.socketID, SOL_SOCKET, SO_RCVBUF, &maxSize, socklen_t(MemoryLayout<Int32>.size)) != 0 {
            //
        }
        //设置最大发送缓冲区
        if setsockopt(socket.socketID, SOL_SOCKET, SO_SNDBUF, &maxSize, socklen_t(MemoryLayout<Int32>.size)) != 0 {
            //
        }
        //非阻塞式
        if fcntl(socket.socketID, F_SETFL, O_NONBLOCK) != 0 {
            //
        }
        
        socket.receiveSource = DispatchSource.makeReadSource(fileDescriptor: self.socketID, queue: self.socketQueue);
        socket.receiveSource?.setEventHandler {
            socket.receiveSourceEvent()
        };
        
        socket.sendSource = DispatchSource.makeWriteSource(fileDescriptor: self.socketID, queue: self.socketQueue);
        socket.sendSource?.setEventHandler {
            socket.sendSourceEvent()
        }
        
        if let acceptHandler = self.acceptHandler {
            acceptHandler(socket)
        }
        
    }
}
//MARK: Receive
extension EZSocket {
    
    public func entrustReceive(timeout: TimeInterval, completion : @escaping (_ data: Data?, _ fromAddress: sockaddr_storage?, _ error: EZError?)->Void) {
        self.cancelReceive()
        self.receiveCompletion = completion
        self.receiveTimeoutInterval = 0
        self.receiveBeginTimestamp = Date.init().timeIntervalSince1970
        if (self.receiveTimeoutInterval > 0) {
            self.beginReceiveTimer();
        }
        self.entrustReceive()
    }
    
    /// 托管式接收的唤醒尝试过程
    /// - Returns: Void
    private func entrustReceive() -> Void {
        
        var error : EZError? = nil;
        var receiveData : Data? = nil;
        var fromAddress: sockaddr_storage? = nil
        
        repeat { // try receive break on error
            if (self.socketID <= 0) {
                error = self.error(code: .DisconnectError);
                break;
            }
            
            guard let buf = self.buffer.baseAddress?.assumingMemoryBound(to: UInt8.self) else {
                error = self.error(code: .StatusError)
                break
            }
            
            var curReceiveLen : Int = 0
            (curReceiveLen, fromAddress) = self.receive(buffer: self.buffer)
            if curReceiveLen > 0 {
                receiveData = Data(bytes: buf, count: curReceiveLen)
            }
            while curReceiveLen == buffer.count {//如果buffer的长度小与单个UDP包的长度，那么需要把包数据拼接起来
                (curReceiveLen, _) = self.receive(buffer: self.buffer, templateAddr: fromAddress)
                if curReceiveLen > 0 {
                    receiveData?.append(buf, count: curReceiveLen)
                }
            }
            
            let curTimestamp : TimeInterval = Date.init().timeIntervalSince1970;
            if (self.receiveTimeoutInterval > 0 && curTimestamp - self.receiveBeginTimestamp >= self.receiveTimeoutInterval) {
                error = self.error(code: .TimeoutError);
                break
            }
            
        }while(false)
        
        if (error != nil || receiveData != nil) {
            if let completion = self.receiveCompletion {
                self.delegateQueue.async {
                    completion(receiveData, fromAddress, error);
                }
            }
            
            if (self.receiveTimeoutInterval == 0 && error == nil) {
                //循环接收，立刻尝试下一次接收
                self.entrustReceive();
            } else {
                //单次接收完毕
                self.cancelReceive();
            }
            
        } else {
            //无数据，等待下次唤醒
            self.resumeReceiveSource();
        }
        
    }
    
    /// 接收
    /// - Parameters:
    ///   - buffer: 缓冲区
    ///   - bufferLen: 缓冲区大小
    /// - Returns: 接收到的大小
    public func receive(buffer : UnsafeMutableRawBufferPointer, templateAddr: sockaddr_storage? = nil) -> (Int, sockaddr_storage?) {
        
        guard self.socketID > 0 else {
            return (-1, nil)
        }
        
        guard !self.connecting else {
            //连接中，不能去接收
            return (-1, nil);
        }
        
        guard let buf = buffer.baseAddress else {
            return (-1, nil)
        }
        
        let recvfromBlock = { (templateAddr: sockaddr_storage) -> (Int, sockaddr_storage?) in
            var templateAddr = templateAddr
            let receiveLen = withUnsafeMutableBytes(of: &templateAddr) { (addrBuffer: UnsafeMutableRawBufferPointer) -> Int in
                guard let addrBuf = addrBuffer.baseAddress?.assumingMemoryBound(to: sockaddr.self) else {
                    return -1
                }
                var addrLen: socklen_t = socklen_t(addrBuf.pointee.sa_len)
                let len: Int = Darwin.recvfrom(self.socketID, buf, buffer.count, 0, addrBuf, &addrLen)
                addrBuf.pointee.sa_len = __uint8_t(addrLen)
                return len
            }
            if receiveLen > 0 {
                return (receiveLen, templateAddr)
            } else {
                return (receiveLen, nil)
            }
        }
        
        var fromAddress: sockaddr_storage? = nil
        var receiveLen : Int = 0;
        if self.connected {
            receiveLen = Darwin.recv(self.socketID, buf, buffer.count, 0);
            if receiveLen > 0 {
                fromAddress = self.serverAddress
            }
        } else if let templateAddr = templateAddr {
            (receiveLen, fromAddress) = recvfromBlock(templateAddr)
        } else if let serverAddress: sockaddr_storage = self.serverAddress {
            (receiveLen, fromAddress) = recvfromBlock(serverAddress)
        } else if let localAddress: sockaddr_storage = self.localAddress {
            var templateAddr = sockaddr_storage()
            templateAddr.ss_len = localAddress.ss_len
            templateAddr.ss_family = localAddress.ss_family
            (receiveLen, fromAddress) = recvfromBlock(templateAddr)
        } else {
            receiveLen = -1;
        }
        return (receiveLen, fromAddress);
    }
    
    private func beginReceiveTimer() -> Void {
        self.receiveTimerSource = DispatchSource.makeTimerSource(flags: [.strict], queue: self.socketQueue);
        self.receiveTimerSource!.schedule(deadline: .now() + self.receiveTimeoutInterval, repeating: .never, leeway: .milliseconds(1));
        self.receiveTimerSource?.setEventHandler(handler: {
            //超时事件触发
            self.cancelReceiveTimer();
            self.entrustReceive();
        });
        self.receiveTimerSource!.resume();
    }
    
    private func cancelReceiveTimer() -> Void {
        if (self.receiveTimerSource != nil) {
            self.receiveTimerSource!.setEventHandler(handler: {});
            self.receiveTimerSource!.setCancelHandler(handler: {});
            self.receiveTimerSource!.cancel();
            self.receiveTimerSource = nil;
        }
    }
    
    func suspendReceiveSource() -> Void {
        if (self.receiveSourceResume) {
            self.receiveSource?.suspend();
            self.receiveSourceResume = false;
        }
    }
    
    public func resumeReceiveSource() -> Void {
        if (self.receiveSourceResume == false) {
            self.receiveSource?.resume();
            self.receiveSourceResume = true;
        }
    }
    
    private func receiveSourceEvent() -> Void {
        guard self.receiveSource?.data ?? 0 > 0 else {
            return
        }
        self.suspendReceiveSource()
        
        if let receiveableHandler = self.receiveableHandler {
            self.delegateQueue.async {
                receiveableHandler()
            }
        }
        
        if self.acceptHandler != nil {
            self.accept()
        } else if self.receiveCompletion != nil {
            self.entrustReceive()
        }
    }
    
}

//MARK: cancel & close
extension EZSocket {
    
    public func cancelReceive() -> Void {
        self.cancelReceiveTimer();
        self.suspendReceiveSource();
        self.receiveTimeoutInterval = 0;
        self.receiveBeginTimestamp = 0;
        self.receiveCompletion = nil;
    }
    
    public func close() -> Void {
        self.cancelReceive();
        if (self.socketID > 0) {
            Darwin.close(self.socketID);
        }
        self.socketID = 0;
        self.clean();
    }
    
    private func clean() -> Void {
        self.connecting = false;
        self.connected = false;
        self.localAddress = nil
        self.ifaName = nil
        self.serverAddress = nil;
        self.saFamily = 0
        if (self.receiveSource != nil) {
            self.receiveSource!.setEventHandler(handler: {});
            self.receiveSource!.cancel();
            self.resumeReceiveSource();
            self.receiveSource = nil;
        }
        if (self.sendSource != nil) {
            self.sendSource!.setEventHandler {};
            self.sendSource!.cancel();
            self.resumeSendSource();
            self.sendSource = nil;
        }
        for packet : Packet in self.sendingPackets {
            let error : EZError = self.error(code: .DisconnectError);
            self.delegateQueue.async {
                packet.completion(error);
            }
        }
        self.sendingPackets.removeAll();
        self.connectedCompletion = nil;
        self.receiveCompletion = nil;
    }
}

//MARK: Utils
extension EZSocket {
    public static func makeUDPSocket(socketQueue: DispatchQueue? = nil) -> EZSocket {
        let socketQueue: DispatchQueue = socketQueue ?? sharedSocketQueue
        return EZSocket.init(socketType: SOCK_DGRAM, protol: IPPROTO_UDP, socketQueue: socketQueue);
    }
    
    public static func makeTCPSocket(socketQueue: DispatchQueue? = nil) -> EZSocket {
        let socketQueue: DispatchQueue = socketQueue ?? sharedSocketQueue
        return EZSocket.init(socketType: SOCK_STREAM, protol: IPPROTO_TCP, socketQueue: socketQueue);
    }
    
    public static func makeICMPSocket(socketQueue: DispatchQueue? = nil) -> EZSocket {
        let socketQueue: DispatchQueue = socketQueue ?? sharedSocketQueue
        return EZSocket.init(socketType: SOCK_DGRAM, protol: IPPROTO_ICMP, socketQueue: socketQueue);
    }
}
